#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WebSocket代理桥接服务使用示例
演示如何使用HTTP API与WebSocket客户端交互
"""

import asyncio
import aiohttp
import json
import logging
from datetime import datetime

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


class WebSocketProxyClient:
    """WebSocket代理客户端示例"""
    
    def __init__(self, api_base_url: str = "http://127.0.0.1:8998"):
        """
        初始化代理客户端
        
        Args:
            api_base_url: HTTP API基础URL
        """
        self.api_base_url = api_base_url.rstrip('/')
        self.session = None
    
    async def __aenter__(self):
        """异步上下文管理器入口"""
        self.session = aiohttp.ClientSession()
        return self
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """异步上下文管理器出口"""
        if self.session:
            await self.session.close()
    
    async def get_health_status(self):
        """获取服务健康状态"""
        try:
            async with self.session.get(f"{self.api_base_url}/health") as response:
                if response.status == 200:
                    data = await response.json()
                    logger.info("服务状态: 健康")
                    logger.info(f"活跃连接数: {data.get('active_connections', 0)}")
                    return data
                else:
                    logger.error(f"健康检查失败: HTTP {response.status}")
                    return None
        except Exception as e:
            logger.error(f"健康检查异常: {str(e)}")
            return None
    
    async def get_active_connections(self):
        """获取活跃连接列表"""
        try:
            async with self.session.get(f"{self.api_base_url}/connections") as response:
                if response.status == 200:
                    data = await response.json()
                    connections = data.get('connections', [])
                    logger.info(f"找到 {len(connections)} 个活跃连接")
                    
                    for i, conn in enumerate(connections):
                        logger.info(f"连接 {i+1}:")
                        logger.info(f"  ID: {conn['connection_id']}")
                        logger.info(f"  客户端: {conn['client_address']}")
                        logger.info(f"  服务端: {conn['server_address']}")
                        logger.info(f"  创建时间: {conn['created_at']}")
                    
                    return connections
                else:
                    logger.error(f"获取连接列表失败: HTTP {response.status}")
                    return []
        except Exception as e:
            logger.error(f"获取连接列表异常: {str(e)}")
            return []
    
    async def send_message_to_connection(self, connection_id: str, message: str, message_type: str = "text"):
        """
        向指定连接发送消息
        
        Args:
            connection_id: 目标连接ID
            message: 要发送的消息
            message_type: 消息类型 ('text' 或 'binary')
        """
        payload = {
            "connection_id": connection_id,
            "message": message,
            "message_type": message_type
        }
        
        try:
            async with self.session.post(
                f"{self.api_base_url}/send",
                json=payload,
                headers={'Content-Type': 'application/json'}
            ) as response:
                
                response_data = await response.json()
                
                if response.status == 200:
                    logger.info(f"✓ 消息发送成功到连接 {connection_id}")
                    logger.info(f"  消息内容: {message[:50]}...")
                    return True
                elif response.status == 404:
                    logger.warning(f"✗ 连接不存在: {connection_id}")
                    return False
                else:
                    logger.error(f"✗ 发送消息失败: {response_data.get('error')}")
                    return False
                    
        except Exception as e:
            logger.error(f"发送消息异常: {str(e)}")
            return False
    
    async def broadcast_message_to_all(self, message: str):
        """向所有活跃连接广播消息"""
        connections = await self.get_active_connections()
        
        if not connections:
            logger.warning("没有活跃连接，无法广播消息")
            return
        
        logger.info(f"开始向 {len(connections)} 个连接广播消息...")
        
        success_count = 0
        for conn in connections:
            connection_id = conn['connection_id']
            success = await self.send_message_to_connection(connection_id, message)
            if success:
                success_count += 1
        
        logger.info(f"广播完成: {success_count}/{len(connections)} 连接成功接收消息")
    
    async def send_periodic_messages(self, interval: int = 10, count: int = 5):
        """
        定期发送消息示例
        
        Args:
            interval: 发送间隔（秒）
            count: 发送次数
        """
        logger.info(f"开始定期发送消息，间隔 {interval} 秒，共 {count} 次")
        
        for i in range(count):
            # 构造消息
            message_data = {
                "type": "periodic_message",
                "sequence": i + 1,
                "total": count,
                "timestamp": datetime.now().isoformat(),
                "content": f"这是第 {i + 1} 条定期消息，来自HTTP API"
            }
            
            message = json.dumps(message_data, ensure_ascii=False, indent=2)
            
            # 广播消息
            await self.broadcast_message_to_all(message)
            
            # 等待下次发送
            if i < count - 1:  # 最后一次不需要等待
                logger.info(f"等待 {interval} 秒后发送下一条消息...")
                await asyncio.sleep(interval)
        
        logger.info("定期消息发送完成")


async def demo_basic_usage():
    """基本使用演示"""
    logger.info("=" * 60)
    logger.info("WebSocket代理桥接服务基本使用演示")
    logger.info("=" * 60)
    
    async with WebSocketProxyClient() as client:
        # 1. 检查服务状态
        logger.info("1. 检查服务健康状态...")
        health_status = await client.get_health_status()
        
        if not health_status:
            logger.error("服务不可用，请确保WebSocket代理桥接服务正在运行")
            return
        
        logger.info("-" * 40)
        
        # 2. 获取连接列表
        logger.info("2. 获取活跃连接列表...")
        connections = await client.get_active_connections()
        
        if not connections:
            logger.warning("当前没有活跃的WebSocket连接")
            logger.info("请启动WebSocket客户端并配置代理后重试")
            return
        
        logger.info("-" * 40)
        
        # 3. 发送单条消息
        logger.info("3. 发送单条测试消息...")
        test_message = json.dumps({
            "type": "test_message",
            "content": "Hello from HTTP API!",
            "timestamp": datetime.now().isoformat()
        }, ensure_ascii=False)
        
        first_connection_id = connections[0]['connection_id']
        await client.send_message_to_connection(first_connection_id, test_message)
        
        logger.info("-" * 40)
        
        # 4. 广播消息
        logger.info("4. 广播消息到所有连接...")
        broadcast_message = json.dumps({
            "type": "broadcast_message",
            "content": "这是一条广播消息，所有连接都会收到",
            "timestamp": datetime.now().isoformat()
        }, ensure_ascii=False)
        
        await client.broadcast_message_to_all(broadcast_message)
        
        logger.info("-" * 40)
        
        # 5. 定期消息发送
        logger.info("5. 定期消息发送演示...")
        await client.send_periodic_messages(interval=5, count=3)


async def demo_interactive_mode():
    """交互模式演示"""
    logger.info("=" * 60)
    logger.info("交互模式演示")
    logger.info("=" * 60)
    
    async with WebSocketProxyClient() as client:
        while True:
            try:
                # 显示菜单
                print("\n请选择操作:")
                print("1. 查看服务状态")
                print("2. 查看活跃连接")
                print("3. 发送消息")
                print("4. 广播消息")
                print("5. 退出")
                
                choice = input("请输入选项 (1-5): ").strip()
                
                if choice == '1':
                    await client.get_health_status()
                    
                elif choice == '2':
                    await client.get_active_connections()
                    
                elif choice == '3':
                    connections = await client.get_active_connections()
                    if connections:
                        connection_id = input("请输入连接ID: ").strip()
                        message = input("请输入消息内容: ").strip()
                        if connection_id and message:
                            await client.send_message_to_connection(connection_id, message)
                    
                elif choice == '4':
                    message = input("请输入广播消息内容: ").strip()
                    if message:
                        await client.broadcast_message_to_all(message)
                    
                elif choice == '5':
                    logger.info("退出交互模式")
                    break
                    
                else:
                    print("无效选项，请重新选择")
                    
            except KeyboardInterrupt:
                logger.info("收到中断信号，退出交互模式")
                break
            except Exception as e:
                logger.error(f"操作异常: {str(e)}")


async def main():
    """主函数"""
    import argparse
    
    parser = argparse.ArgumentParser(description='WebSocket代理桥接服务使用示例')
    parser.add_argument('--mode', choices=['demo', 'interactive'], default='demo',
                       help='运行模式: demo(演示) 或 interactive(交互)')
    parser.add_argument('--api-url', default='http://127.0.0.1:8998',
                       help='HTTP API基础URL')
    
    args = parser.parse_args()
    
    if args.mode == 'demo':
        await demo_basic_usage()
    else:
        await demo_interactive_mode()


if __name__ == "__main__":
    asyncio.run(main())